/************************************************************
 * Project Name         [Thinking_In_Java]
 * File Name            [Example_04_User_Defined_Exceptions.java]
 * Creation Date        [25-Jun-2014]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ************************************************************/
package pkg_03_miscellaneous;

/**
 * 用户自定义异常
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
public class Example_04_User_Defined_Exceptions {

	/**
	 * 异常的抛出
	 * 
	 * @param string
	 * @return 待转换数字开方后的结果
	 * @throws MyFirstException
	 * @throws MySecondException
	 */
	public static double getSqrt(String string) throws UserDefinedException1,
			UserDefinedException2 {
		if (string == null) {
			throw new UserDefinedException1("输入的字符串不能为空");
		}
		double result = 0;
		try {
			result = Double.parseDouble(string);
		} catch (NumberFormatException e) {
			throw new UserDefinedException1("输入的字符串必须能够转化为数字", e);
		}
		if (result < 0) {
			throw new UserDefinedException2("输入的字符串转化成的数字必须大于0");
		}
		return Math.sqrt(result);
	}

	/**
	 * finally语句
	 * 
	 * @param string
	 * @return 方法返回的结果
	 */
	public static double testFinallyA(String string) {
		try {
			System.out.println("try block");
			return getSqrt(string);
		} catch (UserDefinedException1 e) {
			System.out.println("UserDefinedException1 block");
			e.printStackTrace();
			return -1;
		} catch (UserDefinedException2 e) {
			System.out.println("UserDefinedException2 block");
			e.printStackTrace();
			return -2;
		} finally {
			System.out.println("finally block");
		}
	}

	/**
	 * finally语句
	 * 
	 * @param string
	 * @return 方法返回的结果
	 */
	@SuppressWarnings("finally")
	public static double testFinallyB(String string) {
		try {
			System.out.println("try block");
			return getSqrt(string);
		} catch (UserDefinedException1 e) {
			System.out.println("UserDefinedException1 block");
			e.printStackTrace();
			return -1;
		} catch (UserDefinedException2 e) {
			System.out.println("UserDefinedException2 block");
			e.printStackTrace();
			return -2;
		} finally {
			System.out.println("finally block");
			// 在finally语句块中return和throw都是不推荐的, 因为finally语句块中的代码一定会被执行
			// 如果执行这两种语句, 将会导致程序的控制权跳出该方法, 导致try...catch代码块中的返回值被覆盖
			return 0;
		}
	}

	/**
	 * 测试方法
	 * 
	 * @param args
	 *            命令行参数
	 */
	public static void main(String[] args) {

		System.out.println("使用TestFinallyA方法:");
		System.out.println("没发生异常时的输出:");
		System.out.println("result=" + testFinallyA("123.4"));
		System.out.println("发生异常时的输出:");
		System.out.println("result=" + testFinallyA("abcd"));

		System.out.println("使用TestFinallyB方法:");
		System.out.println("没发生异常时的输出:");
		System.out.println("result=" + testFinallyB("123.4"));
		System.out.println("发生异常时的输出:");
		System.out.println("result=" + testFinallyB("-4"));
	}
}

/**
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 */
class UserDefinedException1 extends Exception {

	private static final long serialVersionUID = 2543751446055983018L;

	/**
	 * 构造方法
	 */
	public UserDefinedException1() {
		super();
	}

	/**
	 * 构造方法
	 * 
	 * @param message
	 * @param cause
	 */
	public UserDefinedException1(String message, Throwable cause) {
		super(message, cause);
	}

	/**
	 * 构造方法
	 * 
	 * @param message
	 */
	public UserDefinedException1(String message) {
		super(message);
	}

	/**
	 * 构造方法
	 * 
	 * @param cause
	 */
	public UserDefinedException1(Throwable cause) {
		super(cause);
	}

}

/**
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 */
class UserDefinedException2 extends Throwable {

	private static final long serialVersionUID = -8120323587693664255L;

	/**
	 * 构造方法
	 */
	public UserDefinedException2() {
		super();
	}

	/**
	 * 构造方法
	 * 
	 * @param message
	 * @param cause
	 */
	public UserDefinedException2(String message, Throwable cause) {
		super(message, cause);
	}

	/**
	 * 构造方法
	 * 
	 * @param message
	 */
	public UserDefinedException2(String message) {
		super(message);
	}

	/**
	 * 构造方法
	 * 
	 * @param cause
	 */
	public UserDefinedException2(Throwable cause) {
		super(cause);
	}

}
